<?php

namespace XWAM\Addon\PXCallSystem\Model;

/**
 * TaskModel.class数据库模型
 *
 * @author SoChishun <14507247@qq.com>
 * @version 1.0
 * @since 1.0.0 <2015-4-24> SoChishun Added.
 */
class TaskModel extends AppbaseModel {

    /**
     * 数据表名称
     * @var string
     */
    protected $tableName = 'tcti_task';

    /**
     * 字段定义
     * @var array
     */
    protected $fields = array();

    /**
     * 命名范围
     * @var array
     */
    protected $_scope = array(
        'item_list' => array(
            'field' => 'id,name,taskStrategyID,telsCount,callCount,unCallCount,callRate,callSuccessCount,callFailCount,noAnswerCount,connRate,arriveSeatCount,arriveSeatRate,createdTime,state',
            'order' => 'callRate',
        ),);

    /**
     * 是否批量验证
     * @var boolean
     */
    protected $patchValidate = true;

    /**
     * 验证规则
     * @var array
     */
    protected $_validate = array();

    /**
     * 自动填充
     * @var array
     */
    protected $_auto = array();

    /**
     * 返回任务列表
     * @return type
     * @xince 1.0 <2015-6-17> SoChishun Added.
     */
    public function get_task_list($where) {
        $this->execute('update tcti_task set arriveSeatRate=format((arriveSeatCount/callSuccessCount*100),2)'); // 重新统计到到坐席率 2014-10-30 by sutroon
        $this->execute('update tcti_task set state=0, unCallCount=0, callCount=telsCount, callRate=100 where unCallCount < 0');
        $this->execute('update tcti_task set state=0 where callCount=telsCount or unCallCount=0');
        $orderby = I('sort', $this->_scope['item_list']['order']) . ' ' . I('order');
        $page = I('page', 1) . ',' . I('rows', C('USER.PAGE_SIZE'));
        $total = $this->where($where)->count('id');
        $list = $this->scope('item_list')->where($where)->cache(3)->order($orderby)->page($page)->select(); // 不用缓存，因为kerry会动态修改统计值，会导致统计无法更新
        $out = array();
        foreach ($list as $row) {
            $row['callRateText'] = sofn_trim_end($row['callRate'], '.00');
            $row['connRateText'] = sofn_trim_end($row['connRate'], '.00');
            $row['arriveSeatRateText'] = sofn_trim_end($row['arriveSeatRate'], '.00');
            $row['stateText'] = get_ctitask_text($row['state']);
            $row['createdTimeText'] = substr($row['createdTime'], 0, 10);
            $out[] = $row;
        }
        $sum = array(
            'telsCount' => $this->where($where)->sum('telsCount'),
            'callCount' => $this->where($where)->sum('callCount'),
            'unCallCount' => $this->where($where)->sum('unCallCount'),
            'callSuccessCount' => $this->where($where)->sum('callSuccessCount'),
            'callFailCount' => $this->where($where)->sum('callFailCount'),
        );
        $sum['name'] = '统计：';
        return array('total' => $total, 'rows' => $out, 'footer' => array($sum));
    }

    /**
     * 判断是否超过最大任务数
     * @param int $siteID
     * @param int $tsid
     * @param int $n
     * @return boolean
     * @since 1.0 2014-7-29 by sutroon
     */
    public function check_max_task_num($siteID, $tsid, $n) {
        if (!$tsid || !$siteID) {
            return false;
        }
        $maxTask = $this->table('tuser_member')->where('userType="ADMIN" and siteID=' . $siteID)->getField('maxTask');
        $cursum = $this->where("taskStrategyID=$tsid")->sum('telsCount');
        return ($cursum + $n) <= $maxTask;
    }

    public function import_upload() {
        $rules = array(
            array('taskStrategyID', 'number', '任务策略未选择!', self::MUST_VALIDATE),
            array('rule', 'require', '任务生成规则无效!', self::MUST_VALIDATE),
        );
        if (!$this->validate($rules)->create()) {
            return $this->returnMsg(false, $this->getError());
        }
        $tsid = I('taskStrategyID');
        $siteID = $this->table('tcti_task_strategy')->where('id=' . $tsid)->getField('siteID');
        if (!$siteID) {
            return $this->returnMsg(false, '策略归属有误!');
        }
        $msg = sofn_upload(array('savePath' => 'Import/', 'exts' => array('xlsx', 'xls', 'txt'), 'autoSub' => true, 'subType' => 'date', 'saveName' => array(), 'replace' => TRUE));
        if (!is_array($msg)) {
            return $this->returnMsg(false, $msg);
        }
        $msg = current($msg);
        $this->data['name'] = $this->set_task_name($msg);
        $this->data['prefix'] = I('prefix');
        $this->data['skipDuplicate'] = I('skipDuplicate');
        $this->data['remark'] = I('remark');
        $this->data['filePath'] = $msg['filepath'];
        $this->data['telsCount'] = 0;
        $this->data['createdTime'] = date('Y-m-d H:i:s');
        $this->data['siteID'] = $siteID;
        $this->data['source'] = 'import';
        $result = $this->add();
        return $this->returnMsg($result);
    }

    // 任务名称处理
    function set_task_name($msg) {
        $name = I('name');
        if (!$name) {
            $name = $msg['savename'];
        }
        if (I('prefix')) {
            if (false !== ($pos = strpos($name, '/'))) {
                $name = substr($name, 0, $pos + 1) . I('prefix') . '-' . substr($name, $pos + 1);
            } else {
                $name = I('prefix') . '-' . $name;
            }
        }
        return $name;
    }

    public function import_to_sql($task_id) {
        $data = $this->field('rule, prefix, skipDuplicate, taskStrategyID, filePath, siteID')->find($task_id);
        if (!$data) {
            return $this->returnMsg(false, '任务不存在');
        }
        $tsid = $data['taskStrategyID'];
        $siteID = $data['siteID'];
        $trunkName = $this->table('tcti_task_strategy')->where('id=' . $tsid)->getField('trunkName');
        $prefix = $data['prefix'];
        $rule = $data['rule'];
        $skipDuplicate = $data['skipDuplicate'];

        $path = '.' . $data['filePath'];
        if (!file_exists($path)) {
            $this->returnMsg(false, '文件路径不存在! [' . $path . ']');
        }
        $ext = sofn_get_file_ext($path);
        // 导入txt
        if ('txt' == $ext) {
            $content = file_get_contents($path);
            $arrNumbers = explode(PHP_EOL, $content);
            if ($tsid) {
                if (!$this->check_max_task_num($siteID, $tsid, count($arrNumbers))) {
                    $this->delete($id);
                    return $this->returnMsg(false, '该任务策略中所有任务号码数量已超过您的最大任务数,请在该任务策略中删除部分任务后继续操作!');
                }
            }

            $arrVals = array();
            $tpl = sprintf(sofn_get_config('USER.CALLNUMBER_IMPORT.TXT_FORMAT'), $task_id, $trunkName, $tsid, $siteID);
            foreach ($arrNumbers as $num) {
                $num = trim($num);
                if (!$num) {
                    continue;
                }
                $arrVals[] = sprintf($tpl, $prefix . preg_replace('/[^\d]/i', '', $num));
            }
        } else {
            // 导入Excel
            $arrNumbers = sofn_excel_import($path);
            if ($tsid) {
                if (!$this->check_max_task_num($siteID, $tsid, count($arrNumbers))) {
                    $this->delete($id);
                    return $this->returnMsg(false, '该任务策略中所有任务号码数量已超过您的最大任务数,请在该任务策略中删除部分任务后继续操作!');
                }
            }
            $arrVals = array();
            $tpl = sprintf(sofn_get_config('USER.CALLNUMBER_IMPORT.EXCEL_FORMAT'), $task_id, $trunkName, $tsid, $siteID);
            $user_key = C('USER.USER_KEY');
            foreach ($arrNumbers as $row) {
                switch ($user_key) {
                    case 'XCall':
                        $num = trim($row['号码']);
                        break;
                    case 'TTF':
                        $num = trim($row['电话号码']);
                        break;
                }
                if (!$num) {
                    continue;
                }
                switch ($user_key) {
                    case 'XCall': // 姓名	号码	备注1	备注2	其他备注
                        $arrVals[] = sprintf($tpl, $row['姓名'], $prefix . preg_replace('/[^\d]/i', '', $num), sofn_array_implode(',', $row, 2));
                        break;
                    case 'TTF': // 电话号码	客户姓名	性别	身份证号	卡号	联系地址	备用1	备用2
                        $arrVals[] = sprintf($tpl, $row['客户姓名'], $prefix . $num, $row['性别'], $row['身份证号'], $row['卡号'], $row['联系地址'], $row['备用1'], $row['备用2'], sofn_array_implode(',', $row, 8));
                        break;
                }
            }
        }
        if (!$arrVals) {
            return $this->returnMsg(false, '没有号码!');
        }
        if ($rule == 'random') {
            shuffle($arrVals);
        }
        // 创建临时表
        $table_tmp = sofn_get_sharding_field('DB_IMPORT_TEMP') . 'tcall_number_temp_' . $task_id;
        $table = sofn_get_sharding_field('DB_CALLNUMBER') . 'tcti_call_number' . $tsid;
        AddonD('DbTable')->create_table('CALL_NUMBER', $table_tmp, array('DROPTABLE' => true));
        $count = count($arrVals);
        $n = 0;
        $field = sofn_get_config('USER.CALLNUMBER_IMPORT.FIELDS');
        for ($i = 0; $i < $count; $i++) {
            if ($i % 200 == 0) {
                $sql = implode(',', array_slice($arrVals, 0, 200));
                $this->execute('insert into ' . $table_tmp . ' (' . $field . ') values ' . $sql);
                array_splice($arrVals, 0, 200);
                $n++;
            }
        }
        if (count($arrVals) > 0) {
            $sql = implode(',', $arrVals);
            $this->execute('insert into ' . $table_tmp . ' (' . $field . ') values ' . $sql);
            $n++;
        }
        // 删除自身重复 2015-4-16 SoChishun Added.     
        $skipSelfDuplicate = false;
        if ($skipSelfDuplicate) {
            while (true) {
                mysql_query("delete from $table_tmp where id not in (select * from (select id from $table_tmp where taskID = $task_id group by phoneNumber having count(phoneNumber)>0 limit 1000) t)");
                if (mysql_affected_rows() == 0) {
                    break; // 没得可删了，退出！
                }
                sleep(2); // 每次都要休息一会儿
            }
        }
        if ($skipDuplicate) {
            // 过滤数据库中已经有的
            $dup = $this->execute("delete $table_tmp from $table_tmp INNER JOIN $table on $table_tmp.phoneNumber=tcti_call_number$tsid.phoneNumber where $table_tmp.taskID=$task_id;");
            if (false !== $dup) {
                $count = $count - $dup;
            }
        }
        $this->execute('insert into ' . $table . ' (' . $field . ') select ' . $field . ' from ' . $table_tmp . ' where taskID=' . $task_id);
        $this->where('id=' . $task_id)->setField(array('telsCount' => $count, 'unCallCount' => $count));
        $this->execute('drop table ' . $table_tmp);
        return $this->returnMsg($tsid);
    }

    /**
     * 删除任务(支持批量删除)
     * @param type $ids
     * @return type
     * @since 1.0 <2015-4-29> SoChishun Added.
     */
    public function item_remove($ids) {
        $tasks = $this->where("id in ($ids)")->field('id, state,taskStrategyID')->select();
        if (!$tasks) {
            return $this->returnMsg(false, '任务不存在!');
        }
        $ndo = 0; // 已处理
        $nerr = 0; // 未处理
        $idsdo = array();  // 可处理id
        $tsid = $tasks[0]['taskStrategyID'];
        foreach ($tasks as $row) {
            if ($row['state'] != 0) {
                $nerr++;
            } else {
                $ndo++;
                $idsdo[] = $row['id'];
            }
        }
        if ($idsdo) {
            $stridsdo = implode(',', $idsdo);
            $result = $this->delete($stridsdo);
            if (false === $result) {
                return $this->returnMsg($result);
            }
            $table = sofn_get_sharding_field('DB_CALLNUMBER') . 'tcti_call_number' . $tsid;
            if (count($idsdo) > 1) {
                while (true) {
                    $result = $this->table($table)->where("taskID in ($stridsdo)")->limit(500)->delete();
                    if (false === $result) {
                        die($this->getDbError());
                    }
                    if (0 == $result) {
                        break; // 没得可删了，退出！
                    }
                    usleep(10000); // 每次都要休息一会儿
                }
            } else {
                $this->table($table)->where('taskID=' . $stridsdo)->delete();
            }
        }
        $str = '';
        if ($nerr > 0) {
            $str .= $nerr . '个任务状态有误(请先停止任务),无法删除'.PHP_EOL;
        }
        if ($ndo > 0) {
            $str .= $ndo . '个任务删除成功!';
        }
        return $this->returnMsg(true, $str);
    }

    /**
     * 新增单个号码
     * @return array
     * @since 1.0 <2015-6-24> SoChishun Added.
     */
    public function add_one_number() {
        $validator = array(
            array('phoneNumber', 'require', '电话号码无效!', self::MUST_VALIDATE, 'regex', self::MODEL_INSERT),
            array('taskStrategyID', 'number', '任务策略未选择!', self::MUST_VALIDATE, 'regex', self::MODEL_INSERT),
        );
        $auto = array(
            array('telsCount', 1, self::MODEL_INSERT),
            array('unCallCount', 1, self::MODEL_INSERT),
            array('source', 'add', self::MODEL_INSERT),
            array('createdTime', date('Y-m-d H:i:s'), self::MODEL_INSERT),
        );
        if (!$this->auto($auto)->validate($validator)->create()) {
            return $this->returnMsg(false, $this->getError());
        }
        $tsid = I('taskStrategyID');
        $list = $this->table('tcti_task_strategy')->where('id=' . $tsid)->getField('siteID,trunkName');
        if (!$list) {
            return $this->returnMsg(false, '策略不存在');
        }
        $siteID = key($list);
        $trunkName = current($list);
        if (!$siteID) {
            return $this->returnMsg(false, '策略归属有误!');
        }
        if ($tsid) {
            if (!$this->check_max_task_num($siteID, $tsid, 1)) {
                return $this->returnMsg(false, '该任务策略中所有任务号码数量已超过您的最大任务数,请在该任务策略中删除部分任务后继续操作!');
            }
        }
        $phoneNo = preg_replace('/[^\d]/i', '', I('phoneNumber'));
        $taskName = I('name');
        if (!$taskName) {
            $taskName = $phoneNo;
        }
        $this->name = $taskName;
        $this->siteID = $siteID;
        unset($this->data['phoneNumber']);
        $result = $this->add();
        if (false === $result) {
            return $this->returnMsg($result, var_export($this->getDbError()));
        } else {
            $data['taskID'] = $result;
            $data['trunkName'] = $trunkName;
            $data['taskStrategyID'] = $tsid;
            $data['phoneNumber'] = $phoneNo;
            $data['customerName'] = '';
            $data['source'] = 'add';
            $data['siteID'] = $siteID;
            $table = sofn_get_sharding_field('DB_CALLNUMBER') . 'tcti_call_number' . $tsid;
            $this->table($table)->add($data);
            return $this->returnMsg(true, '执行成功');
        }
    }

}
